﻿using System;
using System.Data.Common;
using System.Windows.Forms;
using Microsoft.Data.ConnectionUI.MySql.Properties;
using Microsoft.VisualStudio.Data;
using MySql.Data.VisualStudio;

namespace Microsoft.Data.ConnectionUI.MySql
{
// ReSharper disable once InconsistentNaming
    public partial class MySqlDataConnectionUI : DataConnectionUIControl
    {
        private bool _dbListPopulated;
        private bool _loadingInProcess;

        public MySqlDataConnectionUI()
        {
            InitializeComponent();
        }

        private bool AttemptToCreateDatabase()
        {
            var connectionProperties = base.ConnectionProperties as MySqlConnectionProperties;
            if (connectionProperties != null)
            {
                DbConnectionStringBuilder connectionStringBuilder = connectionProperties.ConnectionStringBuilder;
                var str = (string) connectionStringBuilder["Database"];
                connectionStringBuilder["Database"] = string.Empty;
                bool flag;
                try
                {
                    using (var support = new MySqlConnectionSupport())
                    {
                        support.Initialize(null);
                        support.ConnectionString = connectionStringBuilder.ConnectionString;
                        support.Open(false);
                        support.ExecuteWithoutResults("CREATE DATABASE `" + dbList.Text + "`", 1, null, 0);
                    }
                    flag = true;
                }
                catch (Exception)
                {
                    MessageBox.Show(string.Format(Resources.ErrorAttemptingToCreateDB, dbList.Text));
                    flag = false;
                }
                finally
                {
                    connectionStringBuilder["Database"] = str;
                }
                return flag;
            }
            throw new Exception(Resources.ConnectionPropertiesNull);
        }

        private bool DatabaseExists()
        {
            var connectionProperties = base.ConnectionProperties as MySqlConnectionProperties;
            if (connectionProperties != null)
            {
                DbConnectionStringBuilder connectionStringBuilder = connectionProperties.ConnectionStringBuilder;
                try
                {
                    using (var support = new MySqlConnectionSupport())
                    {
                        support.Initialize(null);
                        support.ConnectionString = connectionStringBuilder.ConnectionString;
                        support.Open(false);
                    }
                    return true;
                }
                catch (DbException exception)
                {
                    if (!exception.Message.ToLowerInvariant().ToLower().Contains("unknown database"))
                    {
                        throw;
                    }
                    return false;
                }
            }
            throw new Exception(Resources.ConnectionPropertiesNull);
        }

        private void dbList_DropDown(object sender, EventArgs e)
        {
            if (!_dbListPopulated)
            {
                var connectionProperties = base.ConnectionProperties as MySqlConnectionProperties;
                if (connectionProperties != null)
                {
                    DbConnectionStringBuilder connectionStringBuilder = connectionProperties.ConnectionStringBuilder;
                    try
                    {
                        using (var support = new MySqlConnectionSupport())
                        {
                            support.Initialize(null);
                            support.ConnectionString = connectionStringBuilder.ConnectionString;
                            support.Open(false);
                            dbList.Items.Clear();
                            using (DataReader reader = support.Execute("SHOW DATABASES", 1, null, 0))
                            {
                                while (reader.Read())
                                {
                                    string str = reader.GetItem(0).ToString().ToLowerInvariant();
                                    if (str != "information_schema" && str != "mysql")
                                    {
                                        dbList.Items.Add(reader.GetItem(0));
                                    }
                                }
                                _dbListPopulated = true;
                            }
                        }
                    }
                    catch (Exception)
                    {
                        MessageBox.Show(Resources.UnableToRetrieveDatabaseList,
                            Resources.MySqlDataConnectionUI_dbList_DropDown_Error, MessageBoxButtons.OK,
                            MessageBoxIcon.Hand);
                    }
                }
                throw new Exception(Resources.ConnectionPropertiesNull);
            }
        }

        public override void LoadProperties()
        {
            if (base.ConnectionProperties == null)
            {
                MessageBox.Show(Resources.ConnectionPropertiesNull, string.Empty, MessageBoxButtons.OK,
                    MessageBoxIcon.Hand);
                throw new Exception(Resources.ConnectionPropertiesNull);
            }
// ReSharper disable once PossibleNullReferenceException
            var acceptButton = base.ParentForm.AcceptButton as Button;
// ReSharper disable once PossibleNullReferenceException
            acceptButton.Click += okButton_Click;
            var connectionProperties = base.ConnectionProperties as MySqlConnectionProperties;
// ReSharper disable once PossibleNullReferenceException
            DbConnectionStringBuilder connectionStringBuilder = connectionProperties.ConnectionStringBuilder;
            _loadingInProcess = true;
            try
            {
                serverNameTextBox.Text = (string) connectionStringBuilder["Server"];
                userNameTextBox.Text = (string) connectionStringBuilder["User Id"];
                passwordTextBox.Text = (string) connectionStringBuilder["Password"];
                dbList.Text = (string) connectionStringBuilder["Database"];
                savePasswordCheckBox.Checked = (bool) connectionStringBuilder["Persist Security Info"];
            }
            finally
            {
                _loadingInProcess = false;
            }
        }

        private void okButton_Click(object sender, EventArgs e)
        {
            if (!DatabaseExists())
            {
                DialogResult result =
                    MessageBox.Show(string.Format(Resources.UnknownDbPromptCreate, dbList.Text).Replace(@"\n", @"\n"),
                        null, MessageBoxButtons.YesNo, MessageBoxIcon.Question);
// ReSharper disable once PossibleNullReferenceException
                ParentForm.DialogResult = DialogResult.None;
                if (result == DialogResult.Yes)
                {
                    if (!AttemptToCreateDatabase())
                    {
                        MessageBox.Show(string.Format(Resources.ErrorAttemptingToCreateDB), dbList.Text);
                    }
                    else
                    {
                        ParentForm.DialogResult = DialogResult.OK;
                    }
                }
            }
        }

        private void SavePasswordChanged(object sender, EventArgs e)
        {
            if (ConnectionProperties != null && !_loadingInProcess)
            {
                ConnectionProperties[savePasswordCheckBox.Tag as string] = savePasswordCheckBox.Checked;
            }
        }

        private void SetProperty(object sender, EventArgs e)
        {
            try
            {
                if (!_loadingInProcess)
                {
                    var control = sender as Control;
                    if (control != null && (control.Tag.Equals("Server") || control.Tag.Equals("User id")))
                    {
                        _dbListPopulated = false;
                    }
                    if (control != null && control.Tag is string)
                    {
                        ConnectionProperties[control.Tag as string] = control.Text;
                    }
                }
                dbList.Enabled = (serverNameTextBox.Text.Trim().Length > 0) &&
                                 (userNameTextBox.Text.Trim().Length > 0);
            }
// ReSharper disable once EmptyGeneralCatchClause
            catch (Exception)
            {
            }
        }

        private void TrimControlText(object sender, EventArgs e)
        {
            var control = sender as Control;
            if (control != null) control.Text = control.Text.Trim();
        }
    }
}
